#ifndef __MR25HXX_H__
#define __MR25HXX_H__

#include <stdbool.h>
#include <stdint.h>

/**
 * @brief 设备型号枚举类型定义
 */
typedef enum
{
    MR25H256 = 32767,
    MR25H10 = 131071
} mr25hxx_chiptype_t;

/**
 * @brief 设备型号枚举类型定义 Protected Area Unprotected Area
 */
typedef enum
{
    ProtectedAreaNone = 0,         /*无保护0/4*/
    ProtectedAreaUpperQuarter = 1, /*保护高地址区1/4*/
    ProtectedAreaUpperHalf = 2,    /*保护高地址区2/4*/
    ProtectedAreaAll = 3,          /*保护所有地址4/4*/
} mr25hxx_protectedarea_t;

/**
 * @brief MRAM状态寄存器结构体类型定义
 */
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 6000000)
#pragma anon_unions
#endif
typedef union
{
    uint8_t var;
    struct
    {
        uint8_t RES1 : 1; /*Don't care*/
        uint8_t WEL : 1;  /*Write Enable Latch*/
        mr25hxx_protectedarea_t BP : 2;   /*Bank protect*/
        uint8_t RES2 : 3; /*Don't care*/
        uint8_t SRWD : 1; /*Status Register Write Disable*/
    };
} statusregister_t;
/**
 * @brief SPI 8BIT MSB MODE0/3
 *
 */
typedef struct
{
    /*MRAM CS片选控制 形参为true 管脚拉高；反之*/
    void (*wrcs)(bool);
    /*MRAM WP写保护控制 形参为true 管脚拉高；反之*/
    void (*wrwp)(bool);
    /*MRAM HOLD保持控制 形参为true 管脚拉高；反之*/
    void (*wrhold)(bool);
    /*从MRAM读写数据 形参分别为发送缓冲、接收缓冲、发送字节数 注意缓冲指针需支持为NULL情况*/
    int32_t (*txrxbuf)(uint8_t *ptbuf, uint8_t *prbuf, uint32_t len);
} mram_iodrv_t;
/**
 * @brief MRAM 设备结构体定义
 */
typedef struct
{
    struct
    {
        uint32_t inited : 1;              /*初始化完成标志*/
        uint32_t reserved : 2;            /*保护区域设置*/
        uint32_t WEL : 1;                 /*状态寄存器值*/
        mr25hxx_protectedarea_t BP : 2;   /*状态寄存器值*/
        uint32_t SRWD : 1;                /*状态寄存器值*/
        mr25hxx_chiptype_t mramtype : 25; /*型号*/
    };
    mram_iodrv_t io; /*MRAM接口驱动*/
} mr25hxx_t;

int32_t mr25hxx_init(mr25hxx_t *p, mram_iodrv_t *pio,mr25hxx_chiptype_t ct);
int32_t mr25hxx_writeenable(mr25hxx_t *p);
int32_t mr25hxx_writedisable(mr25hxx_t *p);
int32_t mr25hxx_readstatusregister(mr25hxx_t *p, statusregister_t *ps);
int32_t mr25hxx_writestatusregister(mr25hxx_t *p, statusregister_t s);
int32_t mr25hxx_write(mr25hxx_t *p, uint32_t addr, uint8_t *pbuf, uint32_t len);
int32_t mr25hxx_read(mr25hxx_t *p, uint32_t addr, uint8_t *pbuf, uint32_t len);
int32_t mr25hxx_sleep(mr25hxx_t *p);
int32_t mr25hxx_wake(mr25hxx_t *p);

/*demo


#include "mr25hxx.h"
#include <string.h>

void mr25h256_wrcs(bool s)
{
    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, s ? GPIO_PIN_SET : GPIO_PIN_RESET);
}

void mr25h256_wrwp(bool s)
{
}

void mr25h256_wrhold(bool s)
{
}

//SPI MODE0/3 MSB 8BIT
int32_t mr25h256_txrxbuf(uint8_t *ptbuf, uint8_t *prbuf, uint32_t len)
{
    int32_t ret = 0；
    if(NULL == ptbuf)
        ret = HAL_SPI_Receive(&hspi2,prbuf,len,5);
    else if(NULL == prbuf)
        ret = HAL_SPI_Transmit(&hspi2,ptbuf,len,5);
    else
        ret = HAL_SPI_TransmitReceive(&hspi2,ptbuf,prbuf,len,5);
    return ret;
}

//定义并初始化MRAM驱动
const mram_iodrv_t mr25h256_iodrv = {
    .wrcs = mr25h256_wrcs, .wrwp = mr25h256_wrwp, .wrhold = mr25h256_wrhold, .txrxbuf = mr25h256_txrxbuf};
//定义MRAM数据
mr25hxx_t mr25h256;
void main()
{
    uint8_t tx[16];
    uint8_t rx[16];
    mr25hxx_init(&mr25h256, (mram_iodrv_t*)&mr25h256_iodrv, MR25H256);
    while(1)
    {
        memset(tx,tx[15],15);
        //写使能
        mr25hxx_writeenable(&mr25h256);
        //写入数据
        mr25hxx_write(&mr25h256, 0, tx, 16);
        //写失能
        mr25hxx_writedisable(&mr25h256);
        HAL_Delay(1000);
        //读数据
        mr25hxx_read(&mr25h256, 0, rx, 16);
        HAL_Delay(1000);
        //验证数据
        if (0 == memcmp(tx, rx, 16))
        {
            //一致指示
            //run1.cmd.byte = led_invertsingleflash;
        }
        else
        {
            //不一致指示
            //run1.cmd.byte = led_flickering;
        }
        //变换测试值
        tx[15]++;
    }
}
*/
#endif
